package top.zsyle.org.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import sun.font.BidiUtils;
import top.zsyle.basic.config.BussinessException;
import top.zsyle.basic.query.BaseQuery;
import top.zsyle.basic.service.impl.BaseServiceImpl;
import top.zsyle.basic.util.*;
import top.zsyle.basic.vo.ShopVo;
import top.zsyle.org.domain.Employee;
import top.zsyle.org.domain.Shop;
import top.zsyle.org.domain.ShopAuditLog;
import top.zsyle.org.dto.ShopAuditDto;
import top.zsyle.org.dto.ShopSettlementAgainDto;
import top.zsyle.org.eum.ShopStateEnum;
import top.zsyle.org.mapper.EmployeeMapper;
import top.zsyle.org.mapper.ShopAuditLogMapper;
import top.zsyle.org.mapper.ShopMapper;
import top.zsyle.org.service.IShopService;
import top.zsyle.org.dto.EmployeeDto;
import top.zsyle.org.dto.ShopSettlementDto;
import top.zsyle.user.domain.Logininfo;
import top.zsyle.user.mapper.LogininfoMapper;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.validation.constraints.Email;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional
@Slf4j
public class ShopServiceImpl extends BaseServiceImpl<Shop> implements IShopService {

    @Autowired
    private ShopMapper shopMapper;

    @Autowired
    private EmployeeMapper employeeMapper;

    @Autowired
    private ShopAuditLogMapper shopAuditLogMapper;

    @Autowired
    private LogininfoMapper logininfoMapper;


    /**
     * 分页查询
     * 在内存中将auditLogs拼接到shop对象中
     * @param query
     * @return
     */
    @Override
    public PageList<Shop> queryByPage(BaseQuery query) {
        //查询条数
        Integer totals = shopMapper.queryByCount(query);
        if (null == totals || totals == 0) {
            return new PageList<Shop>(0, new ArrayList<>());
        }
        //查询分页
        List<Shop> rows = shopMapper.queryByPage(query);
        //获取店铺的id集和
        List<Long> shopIds = rows.stream().map(Shop::getId).collect(Collectors.toList());
        //根据shopIds获取所有的auditLogs
        List<ShopAuditLog> auditLogs = shopAuditLogMapper.findAllByShopIds(shopIds);
        //对所有的auditLogs按shopId进行分组
        Map<Long,List<ShopAuditLog>> collect =auditLogs.stream().collect(Collectors.groupingBy(ShopAuditLog::getShopId));
        for (Shop shop : rows) {
            List<ShopAuditLog> shopAuditLogs = collect.get(shop.getId());
            shop.setAuditLogs(shopAuditLogs);
        }
        return new PageList<>(totals, rows);
    }

    /**
     * 店铺入驻
     * @param dto
     */
    @Override
    public void settlement(ShopSettlementDto dto) {

        verify(dto);
        save(dto);
    }

    /**
     * 审核（通过、驳回）
     * @param dto
     */
    @Override
    public void audit(ShopAuditDto dto) {
        //1.更改shop店铺状态
        Shop shop = new Shop();
        shop.setId(dto.getShopId());
        String text;
        String path;
        //1.1 判断是: 通过 or 驳回
        if (ShopStateEnum.WATE_ACTIVE.getCode().equals(dto.getState())){
            //已审核通过，待激活
            shop.setState(ShopStateEnum.WATE_ACTIVE.getCode());
            shopMapper.update(shop);
            //2.储存auditLog日志
            saveShopAuditLog(dto);
            //3.发送 通过 邮件给店家
            text = "恭喜您通过了本平台的人工审核，请点击下列链接激活店铺，点击后成功入驻";
            path = "http://localhost:8080/shop/active/";
            EmailUtil.sendShopEmail(dto,text,path);
        }else if(ShopStateEnum.REJECTING.getCode().equals(dto.getState())){
            //驳回
            shop.setState(ShopStateEnum.REJECTING.getCode());
            shopMapper.update(shop);
            //2.储存auditLog日志
            saveShopAuditLog(dto);
            //3.发送 驳回 邮件给店家
            text = "您好，您未通过本平台的人工审核，请点击下列链接重新入住店铺";
            path = "http://localhost:8081/#/registerAgain?shopId=";
            EmailUtil.sendShopEmail(dto,text,path);
        }else{
            throw new BussinessException("审核有问题");
        }
    }

    /**
     * 1、激活业务
     * 2、同时更新 logininfo 表中的数据
     * @param id
     */
    @Override
    public void active(Long id) {
        Shop shopComplete = shopMapper.findById(id);
        //当前店铺管理员
        if (null == shopComplete.getAdminId()){
            throw new BussinessException("该店铺没有管理员！");
        }
        //修改店铺的状态为：已激活
        Shop shop = new Shop();
        shop.setState(ShopStateEnum.ACTIVING.getCode());
        shop.setId(id);
        shopMapper.update(shop);

        Employee empAdmin = employeeMapper.findById(shopComplete.getAdminId());
        //新建logininfo对象
        Logininfo logininfo = new Logininfo();
        logininfo.setUsername(empAdmin.getUsername());
        logininfo.setPhone(empAdmin.getPhone());
        logininfo.setEmail(empAdmin.getEmail());
        logininfo.setSalt(empAdmin.getSalt());
        logininfo.setPassword(empAdmin.getPassword());
        logininfo.setType(0);
        logininfo.setDisable(1);
        //添加店铺管理员登录信息
        logininfoMapper.add(logininfo);
        //更新店铺管理员
        empAdmin.setLogininfoId(logininfo.getId());
        employeeMapper.update(empAdmin);
    }

    /**
     * 获取echarts数据
     * x轴：店铺状态
     * y轴：店铺数量
     * @return
     */
    @Override
    public Map<String, Object> loadShopEcharts() {
        Map<String,Object> data = new HashMap<>();
        //----------------------------------------------------自己的方法
//        List<String> xStr = new ArrayList<>();
//        //获取到页面加载数据的x、y轴数据
        List<ShopVo> shopVos = shopMapper.loadShopEcharts();
//        //x轴为状态码
//        List<Integer> x = shopVos.stream().map(ShopVo::getState).collect(Collectors.toList());
//        for (Integer i : x) {
//            if (ShopStateEnum.WATE_AUDIT.getCode().equals(i)){
//                xStr.add(ShopStateEnum.WATE_AUDIT.getName());
//            } else if (ShopStateEnum.WATE_ACTIVE.getCode().equals(i)){
//                xStr.add(ShopStateEnum.WATE_ACTIVE.getName());
//            } else if (ShopStateEnum.REJECTING.getCode().equals(i)) {
//                xStr.add(ShopStateEnum.REJECTING.getName());
//            } else if (ShopStateEnum.ACTIVING.getCode().equals(i)){
//                xStr.add(ShopStateEnum.ACTIVING.getName());
//            }
//        }
        // y轴为数量
//        List<Integer> y = shopVos.stream().map(ShopVo::getCountNum).collect(Collectors.toList());
//        data.put("x",xStr);
//        data.put("y",y);
        //--------------------------------------------------------------------老毕的方法
        List<String> x = shopVos.stream().map(xx-> ShopStateEnum.getName(xx.getState()))
                .collect(Collectors.toList());
        List<Integer> y = shopVos.stream().map(ShopVo::getCountNum).collect(Collectors.toList());
        data.put("x",x);
        data.put("y",y);
        return data;
    }

    /**
     * 再次店铺入驻
     * @param dto
     */
    @Override
    public void settlementAgain(ShopSettlementAgainDto dto) {
        Shop shop= dto.getShop();
        shop.setId(dto.getId());
        shop.setState(ShopStateEnum.WATE_AUDIT.getCode());
        shopMapper.update(shop);
    }


    /**
     * 储存店铺审核日志
     * @param dto
     */
    private void saveShopAuditLog(ShopAuditDto dto) {
        ShopAuditLog auditLog = new ShopAuditLog();
        auditLog.setAuditTime(new Date());
        auditLog.setShopId(dto.getShopId());
        auditLog.setNote(dto.getNote());
        // todo 暂时不知道审核人id
        auditLog.setAuditId(327);
        shopAuditLogMapper.add(auditLog);
    }

    private void save(ShopSettlementDto dto) {
        //保存店铺信息
        Shop insertShop = dto.getShop();
        shopMapper.add(insertShop);
        //保存员工信息
        Employee insertEmp = dto.getEmployee();
        //使用了主键id自增，mapper.xml中那几个key属性，因此可以获取id
        insertEmp.setShopId(insertShop.getId());
        //加密店铺管理员密码
//        String salt = StrUtils.getComplexRandomString(32);
//        String password = MD5Utils.encrypByMd5(salt + insertEmp.getPassword());
//        insertEmp.setSalt(salt);
//        insertEmp.setPassword(password);
        employeeMapper.add(insertEmp);
        //修改店铺关联的的店长id
        Shop updateShop = new Shop();
        //只需要shop的id和admin_id两个字段就可以
        updateShop.setId(insertShop.getId());
        updateShop.setAdminId(insertEmp.getId());
        shopMapper.update(updateShop);
    }

    private void verify(ShopSettlementDto dto) {
        //校验参数
        //校验两次密码是否一样
        EmployeeDto admin = dto.getAdmin();
        if (!admin.getComfirmPassword().equals(admin.getPassword())){
            throw new BussinessException("两次密码必须相同");
        }
        //百度AI智能检验(店铺名、图片)
        if (!BaiduAuditUtils.TextCensor(dto.getName())){
            throw new BussinessException("店铺名不合规！");
        }
        if(!BaiduAuditUtils.ImgCensor(dto.getLogo())){
            throw new BussinessException("图片不合规");
        }

        //根据店铺phone判断店铺是否存在
        Shop shop = shopMapper.findByPhone(dto.getTel());
        if (null != shop){
            throw new BussinessException("店铺已经存在了！");
        }
        //判断用户是否已经管理了店铺
        Employee employee = employeeMapper.findByUsername(admin.getUsername());
        if (null != employee && null != employee.getShopId()){
            //该用户是该店铺的店员或者管理员
            shop = shopMapper.findByAdminId(employee.getId());
            if (null != shop && shop.getAdminId().equals(employee.getId())){
                throw new BussinessException("该管理员已经绑定了店铺！");
            }
        }
    }
}
